//ldpc控制器
module ldpc_cntrl(
//时钟复位
i_clk,
i_rst_n,
//写时钟写使能
i_w_clk,
i_w_en,
//编解码使能
i_code_en,
i_decode_en,
i_decode_finish,
//编解码地址和数据
i_code_addr,
i_decode_addr,
i_code_final_data,
i_decode_final_data,
//ldpc时钟和读写地址数据
o_ldpc_clk,
o_ldpc_r_addr,
o_ldpc_w_addr,
o_ldpc_w_data
);

//时钟复位
input             i_clk;
input             i_rst_n;
input             i_w_clk;
input             i_w_en;
//编解码使能
input             i_code_en;
input             i_decode_en;
input             i_decode_finish;
//编解码地址和数据
input      [8:0]  i_code_addr;
input      [8:0]  i_decode_addr;
input      [0:31] i_code_final_data;
input      [0:31] i_decode_final_data;
//ldpc时钟和读写地址数据
output reg        o_ldpc_clk;
output reg [8:0]  o_ldpc_r_addr;
output reg [8:0]  o_ldpc_w_addr;
output reg [0:31] o_ldpc_w_data;

//输入数据计数
reg [8:0] r_cnt;

//输入数据计数
always @(posedge i_w_clk or negedge i_rst_n)
if(!i_rst_n)begin
    r_cnt <= 9'b0-1'b1;
end
else if(i_code_en)begin//编码
    if(i_w_en)begin
        if(r_cnt == 9'd255)begin
            r_cnt <= r_cnt;
        end
        else begin
            r_cnt <= r_cnt + 1'b1;
        end
    end
end
else if(i_decode_en)begin//解码
    if(i_w_en)begin
        if(r_cnt == 9'd287)begin
            r_cnt <= r_cnt;
        end
        else begin
            r_cnt <= r_cnt + 1'b1;
        end
    end
end
else begin
    r_cnt <= 9'b0-1'b1;
end

//ldpc时钟
always @(*)
if(i_code_en)begin
    if((r_cnt < 9'd255) && (r_cnt >= 9'd1))begin
        o_ldpc_clk = i_w_clk && i_w_en;
    end
    else if(r_cnt == 9'd255)begin
        o_ldpc_clk = i_clk;
    end
    else begin
        o_ldpc_clk = 1'b0;
    end
end
else if(i_decode_en)begin
    if((r_cnt < 9'd287) && (r_cnt >= 9'd1))begin
        o_ldpc_clk = i_w_clk && i_w_en;
    end
    else if(r_cnt == 9'd287)begin
        o_ldpc_clk = i_clk;
    end
    else begin
        o_ldpc_clk = 1'b0;
    end
end
else begin
    o_ldpc_clk = i_clk;
end

//输入数据地址
always @(posedge o_ldpc_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_ldpc_r_addr <= 9'b0;
end
else if(i_code_en)begin
    if(o_ldpc_r_addr == 9'd255)begin
        o_ldpc_r_addr <= o_ldpc_r_addr;
    end
    else begin
        o_ldpc_r_addr <= o_ldpc_r_addr + 1'b1;
    end
end
else if(i_decode_en)begin
    if(i_decode_finish)begin
        o_ldpc_r_addr <= o_ldpc_r_addr;
    end
    else if(o_ldpc_r_addr == 9'd291)begin
        o_ldpc_r_addr <= 9'b0; 
    end
    else begin
        o_ldpc_r_addr <= o_ldpc_r_addr + 1'b1;
    end
end
else begin
    o_ldpc_r_addr <= 9'b0;
end

//输出数据地址
always @(*)
if(i_code_en)begin
    o_ldpc_w_addr = i_code_addr;
end
else if(i_decode_en)begin
    o_ldpc_w_addr = i_decode_addr;
end
else begin
    o_ldpc_w_addr = 9'b0;
end

//输出数据
always @(*)
if(i_code_en)begin
    o_ldpc_w_data = i_code_final_data;
end
else if(i_decode_en)begin
    o_ldpc_w_data = i_decode_final_data;
end
else begin
    o_ldpc_w_data = 32'b0;
end

endmodule
